

function mypromise(func){
        this.statue = "pending";
        this.data = null;
        this.resolveCallback = [];
        this.rejectCallback = [];
        this._final = null;
        var self = this;
        var resolve = function(data){
          if (data instanceof mypromise) {
            data.then(resolve,reject)
            return;
          }
          setTimeout(function(){
            if(self.statue != "pending") return;
            self.data = data;
            self.statue = "resolve";
            for(var i = 0; i < self.resolveCallback.length; i++){
              var item = self.resolveCallback[i];
              item.bind(self)(data)
            }
          },0)
        }
        var reject = function(data){
          setTimeout(function(){
            if(self.statue != "pending") return;
            self.data = data;
            self.statue = "reject";
            for(var i = 0; i < self.rejectCallback.length; i++){
              var item = self.rejectCallback[i];
              item.bind(self)(data)
            }
          },0)
        }
        try {
          if (typeof func == 'function'){
            func.bind(this)(resolve,reject);
          }else{
            if(func == 'reject'){
              this.statue = "reject";
              reject();
            }else{
              this.statue = "resolve";
              resolve();
            }
          }
        } catch (e) {
          reject(e)
        }
      }
mypromise.prototype.then = function(onresolve,onreject){
  var self = this;
  onresolve = typeof onresolve === 'function' ? onresolve : function(data){return data;}
  onreject = typeof onreject === 'function' ? onreject : function(data){return data;}
  if(self.statue == "pending"){
    return new mypromise(function(resolve,reject){
      var _this = this;
      self.resolveCallback.push(function(data){
        var x = onresolve(data);
        if(x instanceof mypromise){
          x.then(resolve,reject)
        }else{
          resolve(x)
        }
        typeof _this._final == 'function' ? _this._final() : null;
      })

      self.rejectCallback.push(function(data){
        var x = onreject(data);
        if(x instanceof mypromise){
          x.then(resolve,reject)
        }else{
          reject(x)
        }
        typeof _this._final == 'function' ? _this._final() : null;
      })

    });
  }
  if(self.statue == "resolve"){
    return new mypromise(function(resolve,reject){
      var x = onresolve(self.data);
      if(x instanceof mypromise){
        x.then(resolve,reject)
      }else {
        resolve(x);
      }
      typeof this._final == 'function' ? this._final() : null;
    });
  }
  if(self.statue == "reject"){
    return new mypromise(function(resolve,reject){
      var x = onreject(self.data);
      if(x instanceof mypromise){
        x.then(resolve,reject)
      }else {
        reject(x);
      }
      typeof this._final == 'function' ? this._final() : null;
    });
  }
}
mypromise.prototype.catch = function(reject){
  return this.then(null,reject);
}

mypromise.All = function(){
  var allArguments = arguments;
  var len = allArguments.length,
      item = null,
      successResult = [],
      failResult = []
      resultData = [];
  return new mypromise(function(resolve,reject){
    function resolver(index){
      return function(data){
        successResult.push(1);
        resolveAll(index,data);
      }
    }
    function rejecter(index){
      return function(data){
        failResult.push(1);
        resolveAll(index,data);
      }
    }
    function resolveAll(index,data){
      resultData.push({index:index,data:data})
      if(successResult.length + failResult.length == len){
        if( successResult.length == len){
          resolve(resultData)
        }else{
          reject(data)
        }
      }
    }
    for(var i = 0; i < len; i++){
      item = allArguments[i];
      if(!(item instanceof mypromise)){
        throw new TypeError("you must pass promise to mypromise.all")
      }
      item.then(resolver(i),rejecter(i))
    }
  })
}
mypromise.Race = function(){
  var allArguments = arguments;
  var len = allArguments.length,
      item = null,
      successResult = [],
      failResult = [];
  return new mypromise(function(resolve,reject){
    function resolver(data){
      successResult.push(1);
      resolveAll(data);
    }
    function rejecter(data){
        failResult.push(1);
        reject(data);
    }
    function resolveAll(data){
      resolve(data)
    }
    for(var i = 0; i < len; i++){
      item = allArguments[i];
      if(!(item instanceof mypromise)){
        throw new TypeError("you must pass promise to mypromise.all")
      }
      item.then(resolver,rejecter)
    }
  })
}
mypromise.Resolve = function(func){
  if(func instanceof mypromise){
    return func;
  }else{
    return new mypromise('resolve');
  }
}
mypromise.Reject = function(func){
  return new mypromise('reject');
}
mypromise.prototype.Final = function(onresolve){
  this._final = onresolve;
}

function axios(options){
  var AX = new myaxios();
  return AX.send(options);
}
function myaxios(){

}
myaxios.prototype.send = function(options){
  var _this = this;
  return new Promise(function (resolve, reject) {
      var xhr = new XMLHttpRequest();
      var baseUrl = options.baseUrl;
      var url = options.url;
      if(!!baseUrl){
        url = baseUrl + url;
      }
      if(options.type == "get" && options.data != null){
        url = url + _this.queryParms(options.data);
      }
      xhr.onreadystatechange = function(){
          if ( xhr.readyState == 4 && xhr.status == 200 ) {
            if(isNaN(xhr.responseText)){
                resolve(JSON.parse(xhr.responseText));
            }else{
                resolve(xhr.responseText);
            }
              
          }
          if ( xhr.readyState == 4 && xhr.status != 200 ) {
              reject(xhr.status);
          }
      };
      xhr.open(options.type, url);
      xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      if(options.type == "post" && options.data != null){
        var parm = _this.queryParms(options.data,1);
        xhr.send(parm);
      }else{
        xhr.send();
      }
  });
}
myaxios.prototype.queryParms = function(parm,p){
  var parmStr = "";
  for(var key in parm){
    parmStr = parmStr + "&" + key + "=" + parm[key];
  }
  if(!!p){
    parmStr = parmStr.replace("&","");
  }else{
    parmStr = parmStr.replace("&","?");
  }
  return parmStr;
}
